package com.lyx.blogspace.jwt.service;

import com.lyx.blogspace.common.domain.dos.UserDO;
import com.lyx.blogspace.common.domain.dos.UserRoleDO;
import com.lyx.blogspace.common.domain.mapper.UserMapper;
import com.lyx.blogspace.common.domain.mapper.UserRoleMapper;
import com.lyx.blogspace.jwt.exception.UsernameOrPasswordNullException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author by lyx
 * 根据加载的用户信息，创建一个 Spring Security 所需的 UserDetails 对象，包含用户名、密码、角色和权限等。
 */
@Service
@Slf4j
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 从数据库中查询
        UserDO user = userMapper.findByUsername(username);
        if (Objects.isNull(user)) {
            throw new UsernameNotFoundException("用户不存在！");
        }
        List<UserRoleDO> userRoleDOS = userRoleMapper.selectByUsername(username);
        String[] userRoleArr = null;
        if (!CollectionUtils.isEmpty(userRoleDOS)) {
            List<String> list = userRoleDOS.stream().map(UserRoleDO::getRole).collect(Collectors.toList());
            userRoleArr = list.toArray(new String[list.size()]);
        }

        // 暂时先写死，密码为 lyxianowo, 这里填写的密文，数据库中也是存储此种格式
        // authorities 用于指定角色，这里写死为 ADMIN 管理员
        return User.withUsername(user.getUsername())
            .password(user.getPassword())
            .authorities(userRoleArr)
            .build();
    }
}
